﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace XmlWork
{
    /// <summary>
    /// Класс для работ по чтению/записи настроек в xml.
    /// </summary>
    class WorkWithXML
    {
		public const string SRT_MAINWINDOWCONFIG = "MainWindowConfig";

        /// <summary>
        /// Событие - нужен новый объект для записи в него настроек.
        /// </summary>
        public static event EventHandler NeedNewObject;

        private static void OnNeedNewObject(EventArgs e)
        {
            EventHandler handler = NeedNewObject;
            if (handler != null)
                handler(null, e);
        }

        /// <summary>
        /// Сохранить настройки в XML файл
        /// </summary>
        /// <param name="filePath">Имя файла для сохранения</param>
        /// <param name="objs">Коллекция объектов, реализующих IXmlWorker, из которых происходит вызов данного метода</param>
        public static void SaveToXmlFile(string filePath, ref List<IXmlWorker> objs)
        {
            FileStream fs = new FileStream(filePath, FileMode.Create);
            XmlTextWriter xmlOut = new XmlTextWriter(fs, Encoding.UTF8);

            xmlOut.Formatting = Formatting.Indented;

            xmlOut.WriteStartDocument();
            xmlOut.WriteComment("Config file");
            xmlOut.WriteStartElement("Config");

            foreach (var obj in objs)
            {
                obj.SaveToFile(ref xmlOut);
            }

            xmlOut.WriteEndElement();
            xmlOut.WriteEndDocument();
            xmlOut.Close();
            fs.Close();
        }

		/// <summary>
		/// Сохранить настройки в XML файл
		/// </summary>
		/// <param name="filePath">Имя файла для сохранения</param>
		/// <param name="obj">Oбъект, реализующий IXmlWorker, из которого происходит вызов данного метода</param>
		public static void SaveToXmlFile(string filePath, ref IXmlWorker obj)
		{
			List<XmlWork.IXmlWorker> objs = new List<XmlWork.IXmlWorker>();
			objs.Add(obj);
			SaveToXmlFile(filePath, ref objs);
		}

        /// <summary>
        /// Загрузить настройки из XML файла
        /// </summary>
        /// <param name="filePath">Имя файла с настройками</param>
		/// <param name="xmlNodeMarker">Маркер для обозначения начала блока данных с настройками</param>
        /// <param name="objs">Коллекция объектов, реализующих IXmlWorker, из которых происходит вызов данного метода</param>
        public static void ReadFromXmlFile(string filePath, string xmlNodeMarker, ref List<IXmlWorker> objs)
        {
            FileStream fs = new FileStream(filePath, FileMode.Open);
            XmlTextReader xmlIn = new XmlTextReader(fs);
            xmlIn.WhitespaceHandling = WhitespaceHandling.None;
            xmlIn.MoveToContent();

            if (xmlIn.Name != "Config")
                throw new ArgumentException("Incorrect file format.");

            do
            {
                if (!xmlIn.Read())
                    throw new ArgumentException("Error @ read file.");
                if (xmlIn.NodeType == XmlNodeType.EndElement && xmlIn.Name == "Config")
                    break;
                if (xmlIn.NodeType == XmlNodeType.EndElement)
                    continue;

				if (xmlIn.NodeType == XmlNodeType.Element && (xmlIn.Name == xmlNodeMarker || xmlIn.Name == WorkWithXML.SRT_MAINWINDOWCONFIG))
				{
					OnNeedNewObject(new EventArgs());
					objs[objs.Count - 1].ReadFromFile(xmlIn);
				}
            }
            while (!xmlIn.EOF);

            xmlIn.Close();
            fs.Close();
        }

        /// <summary>
        /// Загрузить настройки из XML файла
        /// </summary>
        /// <param name="filePath">Имя файла с настройками</param>
		/// <param name="xmlNodeMarker">Маркер для обозначения начала блока данных с настройками</param>
        /// <param name="objs">Коллекция объектов, реализующих IXmlWorker, из которых происходит вызов данного метода</param>
		public static void ReadFromXmlFile(string filePath, string xmlNodeMarker, ref IXmlWorker obj)
		{
			List<XmlWork.IXmlWorker> objs = new List<XmlWork.IXmlWorker>();
			objs.Add(obj);
			ReadFromXmlFile(filePath, xmlNodeMarker, ref objs);
		}
    }
}
